﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Windows;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using NLog;
using SellAvi.Model;
using SellAvi.Services;

namespace SellAvi.ViewModel
{
    public class ProductImportViewModel : ViewModelBase
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        public IDataAccessService ServiceProxy { get; set; }
        public RelayCommand PasteDataCommand { get; set; }
        public RelayCommand CleanImportCommand { get; set; }
        public RelayCommand RemoveDuplicatesCommand { get; set; }
        public RelayCommand SaveProductsCommand { get; set; }
        public RelayCommand<DragEventArgs> DropFileCommand { get; set; }
        public ObservableCollection<AvitoProduct> ImportedProducts { get; set; }
        private AvitoUser _currentAvitoUser;

        public ProductImportViewModel(IDataAccessService servPxy)
        {
            ServiceProxy = servPxy;
            PasteDataCommand = new RelayCommand(PasteExcelData);
            CleanImportCommand = new RelayCommand(CleanImport);
            RemoveDuplicatesCommand = new RelayCommand(RemoveDuplicates);
            SaveProductsCommand = new RelayCommand(SaveProducts);
            DropFileCommand = new RelayCommand<DragEventArgs>(DragAndDropFiles);

            ImportedProducts = new ObservableCollection<AvitoProduct>();
            Messenger.Default.Register<AvitoUser>(this, (au) =>
            {
                _currentAvitoUser = au;
            });
        }
        public int ImportedLines { get; set; }
        public int ImportedErrors { get; set; }
        public int ImportedImages { get; set; }

        public int ImportedImagesTotal
        {
            get
            {
                return ImportedProducts.Count(x => x.MainProductImage != null);
            }
        }

        public string ImportMessage { get; set; }

        private void CleanImport()
        {
            ImportedProducts.Clear();
            ImportedLines = 0;
            ImportedErrors = 0;
            ImportedImages = 0;
            RaisePropertyChanged("ImportedProducts");
            RaisePropertyChanged("ImportedLines");
            RaisePropertyChanged("ImportedErrors");
            RaisePropertyChanged("ImportedImages");
            RaisePropertyChanged("ImportedImagesTotal");
        }

        private void RemoveDuplicates()
        {
            //TODO: http://proudmonkey.azurewebsites.net/various-ways-to-get-distinct-values-from-a-listt-using-linq/
            var dup = ImportedProducts.GroupBy(x => x.Title);
            //ImportedProducts.Add(query);
            RaisePropertyChanged("ImportedProducts");
        }

        private void PasteExcelData()
        {
            if (ChoosenRegion == null || ChoosenCategory == null || ChoosenParameter == null)
            {
                MessageBox.Show("Предварительно укажите регион, категорию и тип товара!");
                return;
            }
            ImportedLines = 0;
            ImportedErrors = 0;
            ImportedImages = 0;
            ImportMessage = null;

            var csvData = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
            if (csvData != null)
            {
                CleanImport();
                foreach (var line in csvData.Split(Environment.NewLine.ToCharArray()).Where(x => x.Contains(";")))
                {
                    //TODO: добавить щетчик для ProgressBar

                    var newProduct = new AvitoProduct();
                    var lineElements = line.Split(';');
                    if (lineElements.Length > 2)
                    {

                        newProduct.AvitoUser = _currentAvitoUser;
                        newProduct.Region = ChoosenRegion;
                        newProduct.Category = ChoosenCategory;
                        newProduct.Param = ChoosenParameter;
                        newProduct.DateInsert = DateTime.Now;

                        newProduct.Title = lineElements[0];
                        newProduct.Description = lineElements[1];
                        newProduct.Price = lineElements[2];

                        ImportedProducts.Add(newProduct);
                        ImportedLines++;
                    }
                    else
                    {
                        ImportedErrors++;
                        ImportMessage += ("Ошибка в строке: " + line + Environment.NewLine);
                    }
                    if (lineElements.ElementAtOrDefault(3) != null && File.Exists(lineElements[3]) && HasImageExtension(lineElements[3]))
                    {
                        var localFileName = UploadSingleImage(lineElements[3]);
                        if (localFileName != null)
                        {
                            var ai = new AvitoImage() { LocalFileName = localFileName };
                            newProduct.AvitoImages.Add(ai);
                            ImportedImages++;
                        }
                    }

                }
                ImportMessage += ("Импорт товаров завершен! ");

            }
            else
            {
                MessageBox.Show("Программа не может импортировать данные из буфера обмена!", "Ошибка импорта", MessageBoxButton.OK, MessageBoxImage.Error);
                ImportMessage =
                    "Выделите и скопируйте 3 основные колонки 'заголовок','описание','цена' из таблицы Excel!";
            }
            RaisePropertyChanged("ImportedProducts");
            RaisePropertyChanged("ImportedLines");
            RaisePropertyChanged("ImportedImages");
            RaisePropertyChanged("ImportedErrors");
            RaisePropertyChanged("ImportMessage");

        }

        private void DragAndDropFiles(DragEventArgs drgevent)
        {
            if (ImportedProducts == null || ImportedProducts.Count == 0)
            {
                MessageBox.Show(
                    "Перед тем как добавлять изображения, убедитесь что вы импортировали более одного товара!");
                ImportMessage =
                    "Фотографии будут добавлены к товарам автоматически в тойже последовательности что и товар";
                return;
            }

            ImportedImages = 0;
            drgevent.Handled = true;
            // Check that the data being dragged is a file
            if (drgevent.Data.GetDataPresent(DataFormats.FileDrop))
            {
                // Get an array with the filenames of the files being dragged
                string[] files = (string[])drgevent.Data.GetData(DataFormats.FileDrop);
                foreach (var file in files)
                {
                    if (!HasImageExtension(file))
                        continue;

                    var pr = ImportedProducts.FirstOrDefault(x => x.MainProductImage == null);
                    if (pr != null)
                    {
                        var localFileName = UploadSingleImage(file);
                        if (localFileName != null)
                        {
                            var ai = new AvitoImage() { LocalFileName = localFileName };
                            pr.AvitoImages.Add(ai);
                        }

                    }
                    else
                    {
                        ImportMessage = ("Допустимых фотографий для импорта: " + ImportedProducts.Count);
                    }

                }
                ImportedImages = files.Count();
                RaisePropertyChanged("ImportedImages");
                RaisePropertyChanged("ImportedImagesTotal");
                RaisePropertyChanged("ImportMessage");
                RaisePropertyChanged("ImportedProducts");
            }
            drgevent.Effects = DragDropEffects.None;
        }
        public bool HasImageExtension(string source)
        {
            return (source.EndsWith(".png") || source.EndsWith(".jpg") || source.EndsWith(".jpeg"));
        }

        public string UploadSingleImage(string file)
        {
            var localFileName = Guid.NewGuid() + new FileInfo(file).Extension;
            try
            {
                File.Copy(file, Path.GetFullPath("images/" + Path.GetFileName(localFileName)), true);
            }
            catch (Exception)
            {
                ImportMessage += ("Ошибка копирования изображения в папку с программой: " + Path.GetFileName(file) +
                                  Environment.NewLine);
            }
            return localFileName;
        }
        private void SaveProducts()
        {
            if (ImportedProducts.Count>0)
            {
                try
                {
                    foreach (var importedProduct in ImportedProducts)
                    {
                        ServiceProxy.CreateProduct(importedProduct);
                    }
                    ServiceProxy.SaveContext();
                    MessageBox.Show(String.Format("Успешно импортировано {0}х товаров \r\nПерейдите в каталог для просмотра", ImportedProducts.Count),
                   "Импорт товаров завершен", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                catch (Exception ex)
                {
                    Logger.Error(ex, "Возникла ошибка при попытке сохранения импортируемых товаров");

                }
            }
        }

        #region Регион Категория Товар
        private TRegion _choosenRegion;
        public TRegion ChoosenRegion
        {
            get { return _choosenRegion; }
            set
            {
                _choosenRegion = value;
                RaisePropertyChanged("ChoosenRegion");
            }
        }

        private TCategory _choosenCategory;
        public TCategory ChoosenCategory
        {
            get { return _choosenCategory; }
            set
            {
                _choosenCategory = value;
                RaisePropertyChanged("TFilteredParameters");
                RaisePropertyChanged("ChoosenCategory");
            }
        }

        private TParam _choosenParameter;
        public TParam ChoosenParameter
        {
            get { return _choosenParameter; }
            set
            {
                _choosenParameter = value;
                RaisePropertyChanged("ChoosenParameter");
            }
        }

        public ObservableCollection<TParam> TFilteredParameters
        {
            get
            {
                if (ChoosenCategory != null)
                {
                    return new ObservableCollection<TParam>(ServiceProxy.GetParams.Where(x => x.CategoryId == ChoosenCategory.Id));
                }
                return null;
            }
        }
        #endregion

    }
}